/* ---------------------------------- http ---------------------------------- */
require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` });     // 加载环境变量
const express = require('express')
const fs = require('fs');
const server = express()
const jwt = require('jsonwebtoken');
const cors = require('cors')
const globalVars = require('./global/index')

const ws = require('ws')
const tool = require('./utils/tool');
const { default: axios } = require('axios');
const dayjs = require('dayjs');


server.use(cors())

//token密钥
let secret = 'doublefly'

console.log(process.env.NODE_ENV, process.env.BASE_HOST);


// 注册解析数据的中间件
server.use(express.json(), express.urlencoded())
server.use(express.static('./static'))
server.use(express.static('./images'))


//路由白名单
let wilteList = [
    '/api/banner/getBanner',
    '/api/banner/updateBannerText',
    '/api/banner/updateBannerPhoto',
    '/api/login/register',
    '/api/login/login',
    '/api/login/existUsername',
    '/api/login/registerUser',
    '/api/article/getArticle',
    '/api/article/getDetail',
    '/api/article/uploadImg',
    '/api/admin/getUserList',
    '/api/admin/changeIce',
    '/api/admin/getUserCount',
    '/api/admin/getArticleList',
    '/api/admin/changeArticleStatus',
    '/api/admin/getBannerList',
    '/api/admin/getTypePercent',
    '/api/admin/getHotAuthor',
    '/api/admin/getHotArticle',
    '/api/admin/getMonthArticleCount',
    '/api/user/updateAvatar',
    '/api/uploadTest/uploadFile',
    '/api/SSEMessage',
    '/api/chat/askDeepSeek',
]

// 验证token的中间件
server.use((req, res, next) => {
    let url = req._parsedUrl.pathname
    // 如果请求的路由在白名单中就放行
    // 用于放行那些不需要登录就可以访问的路由
    if (wilteList.includes(url)) {
        next()
        return
    }
    let photoReg = /\.(jpg|jpeg|JPG|JPEG)$/
    if (photoReg.test(url)) {
        next()
        return
    }
    // 否则验证token，判断当前是否已经登录
    let token = req.headers.authorization
    jwt.verify(token, secret, (error, decoded) => {
        if (error) {
            res.send({
                code: 400,
                msg: '未登录！',
                error
            })
            return
        }
        let info = {
            ...decoded
        }
        req.info = info
        next();
    })
})


const banner = require('./apis/banner')
server.use('/api/banner', banner)
const article = require('./apis/article')
server.use('/api/article', article)
const login = require('./apis/login')
server.use('/api/login', login)
const user = require('./apis/user')
server.use('/api/user', user)
const admin = require('./apis/admin')
server.use('/api/admin', admin)
const me = require('./apis/me')
server.use('/api/me', me)
const follow = require('./apis/follow')
server.use('/api/follow', follow)
const message = require('./apis/message')
server.use('/api/message', message)
const chat = require('./apis/chat')
server.use('/api/chat', chat)
const goods = require('./apis/goods')
server.use('/api/goods', goods)



const uploadTest = require('./apis/uploadTest')
server.use('/api/uploadTest', uploadTest)


/* --------------------------------- SSE消息推送 -------------------------------- */
server.get('/api/SSEMessage', (req, res) => {
    const { token, user_id } = req.query
    jwt.verify(token, secret, (error, decoded) => {
        if (error) {
            // 如果 token 无效，返回错误或拒绝连接
            res.status(403).send('Unauthorized');
        } else {
            res.setHeader('Content-Type', 'text/event-stream');
            res.setHeader('Cache-Control', 'no-cache');
            res.setHeader('Connection', 'keep-alive');
            // res.flushHeaders(); // 确保立即发送响应头

            // 存储所有活动的 SSE 客户端
            globalVars.SSEClients.set(user_id, res);
            // console.log('globalVars.SSEClients', globalVars.SSEClients);


            // 当客户端断开连接时，从集合中移除
            req.on('close', () => {
                globalVars.SSEClients.delete(user_id);
            });

            // 发送一个初始化事件
            res.write(`data: ${JSON.stringify([])}\n\n`);
        }

    })
})


// 监听服务器运行的端口BASE_URL_PORT
server.listen(process.env.BASE_URL_PORT, () => {
    console.log(`server is running at ${process.env.BASE_URL}`);
})



/* -------------------------------- websocket ------------------------------- */
const wss = new ws.WebSocketServer({
    port: 8083
})



wss.on('connection', socket => {
    console.log('connection');

    // message事件的回调函数
    const messageHandler = data => {
        const message = JSON.parse(data.toString())
        if (message.type === 'login') {
            socket.nickname = message.nickname
            socket.avatar = message.avatar
            Array.from(wss.clients).forEach(client => {
                client.send(JSON.stringify({
                    type: 'clients',
                    clients: Array.from(wss.clients).map(item => {
                        return { nickname: item.nickname, avatar: item.avatar }
                    })
                }))
                if (client === socket) {    // 如果用户是自己
                    socket.send(JSON.stringify({
                        type: 'login-success',
                        name: message.nickname,
                        // clients: wss.clients
                    }))

                } else {    // 如果用户不是自己
                    client.send(JSON.stringify({
                        type: 'user-join',
                        name: message.nickname,
                    }))
                }
            })
        } else if (message.type === 'send') {     // 用户发送信息
            Array.from(wss.clients).forEach(client => {
                client.send(JSON.stringify({
                    type: client === socket ? 'me-send' : 'other-send',
                    name: socket.nickname,
                    avatar: socket.avatar,
                    text: message.text,
                    time: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
                }))
            })
        } else if (message.type === 'face') {   // 用户发送图片表情时
            Array.from(wss.clients).forEach(client => {
                client.send(JSON.stringify({
                    type: client === socket ? 'me-send' : 'other-send',
                    name: socket.nickname,
                    avatar: socket.avatar,
                    text: message.text,
                    time: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'),
                    isMedia: 'face'
                }))
            })
        } else if (message.type === 'file') {   // 用户发送文件时
            Array.from(wss.clients).forEach(client => {
                client.send(JSON.stringify({
                    type: client === socket ? 'me-send' : 'other-send',
                    name: socket.nickname,
                    avatar: socket.avatar,
                    text: message.text,
                    time: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'),
                    isMedia: 'file'
                }))
            })
        } else if (message.type === 'callDS') { //用户提问DS时
            let messageId = dayjs().valueOf()
            axios({
                method: 'get',
                url: `${process.env.BASE_URL}/api/chat/askDeepSeek`,
                params: {
                    message: message.text ? message.text.substring(10) : '',
                }
            }).then(res => {
                console.log(res.data);
                // ds的回答
                Array.from(wss.clients).forEach(client => {
                    client.send(JSON.stringify({
                        messageId: messageId,
                        type: 'other-send',
                        name: 'DeepSeek',
                        avatar: `${process.env.BASE_URL}/images/avatar/ds.jpg`,
                        text: `@${socket.nickname} ${res.data}`,
                        time: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
                    }))
                })
            })
            // 用户的提问
            Array.from(wss.clients).forEach(client => {
                client.send(JSON.stringify({
                    // messageId: messageId,
                    type: client === socket ? 'me-send' : 'other-send',
                    name: socket.nickname,
                    avatar: socket.avatar,
                    text: message.text,
                    time: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
                }))
            })
            setTimeout(() => {
                // 正在思考中的占位内容
                Array.from(wss.clients).forEach(client => {
                    client.send(JSON.stringify({
                        messageId: messageId,
                        type: 'other-send',
                        name: 'DeepSeek',
                        avatar: `${process.env.BASE_URL}/images/avatar/ds.jpg`,
                        text: `正在思考${socket.nickname}的问题...`,
                        status: 'thinking',
                        time: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
                    }))
                })
            }, 500)


        } else if (message.type === 'close') {
            Array.from(wss.clients).forEach(client => {
                if (socket !== client) {
                    client.send(JSON.stringify({
                        type: 'other-close',
                        name: socket.nickname
                    }))
                }
            })
        }
    }

    socket.on('open', () => {
        console.log('open');
    })

    socket.on('error', (error) => {
        console.log('error', error);
    })

    socket.on('message', messageHandler)

    socket.on('close', () => {
        console.log('close', wss.clients);
        // 展示当前在线的用户
        Array.from(wss.clients).forEach(client => {
            client.send(JSON.stringify({
                type: 'clients',
                clients: Array.from(wss.clients)
            }))
        })

    })
})